<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge,chrome=1">
  <title>Document</title>
  <script src="./library/jquery-3.6.0.js"></script>
  <script src="./library/vue-2.6.14.js"></script>
  <link rel="stylesheet" href="./index.css">
  <style>
    [v-cloak] {
      display: none;
    }

    .barArea {
      margin: 30px;
      display: flex;
      align-items: center;
      font-size: 14px;
    }

    .fnBtn {
      border: 1px #666 solid;
      border-radius: 6px;
      margin-right: 24px;
      padding: 3px 6px;
    }

    input[type=file] {
      border: 1px #999 solid
    }

    input[type=file]:active,
    input[type='file']:focus {
      outline: none;
    }
  </style>
</head>

<body>
  <div id="app" style="margin-bottom: 1000px;">
    <div v-for="(item,index) in dataArr" :key="item.id" v-cloak>
      <div class="barArea" v-if="item.type === 'text'">
        <div class="es-richText" style="width: 750px;">
          <div class="toolbar hide" :listid="item.id">
            <div class="toHtml_btn" onclick="esEditor.toHtml($(this))" style="font-size:12px;">&lt;/&gt;</div>
            <div class="toView_btn" onclick="esEditor.toView($(this))" style="font-size:12px;display:none;">TXT</div>
            <div class="htmlHide" onclick="esEditor.undo()">撤销</div>
            <div class="htmlHide" onclick="esEditor.redo()">恢复</div>
            <div class="htmlHide" onclick="esEditor.insertEMSP()">EMSP</div>
            <div class="htmlHide" onclick="esEditor.indent()">缩进</div>
            <div class="htmlHide" onclick="esEditor.bold()">加粗</div>
            <div class="htmlHide" onclick="esEditor.italic()">倾斜</div>
            <div class="htmlHide" onclick="esEditor.underline()">下划线</div>
            <div class="htmlHide" onclick="esEditor.strikeThrough()">删除线</div>
            <div class="htmlHide" onclick="esEditor.h1()">H1</div>
            <div class="htmlHide" onclick="esEditor.h2()">H2</div>
            <div class="htmlHide" onclick="esEditor.h3()">H3</div>
            <div class="htmlHide" onchange="esEditor.size()">字体大小</div>
            <input class="htmlHide" type="number" onchange="esEditor.fontSize($(this).val())" />
            <div class="htmlHide" onclick="esEditor.foreColor()">字体颜色</div>
            <div class="htmlHide" onclick="esEditor.hiliteColor()">字体背景</div>
            <div class="htmlHide" onclick="esEditor.insertOrderedList()">有序</div>
            <div class="htmlHide" onclick="esEditor.insertUnorderedList()">无序</div>
            <div class="htmlHide" onclick="esEditor.save()">提交</div>
            <div class="htmlHide" onclick="esEditor.format()">format</div>
            <div class="htmlHide" onclick="esEditor.lineHeight()">行高</div>
          </div>
          <div style="width:100%; height:300px; box-sizing: border-box;">
            <!-- :src="'?ids='+index" -->
            <iframe class="HtmlEdit" style="width:100%;height:100%;"></iframe>
            <textarea class="HtmlView" onblur="" style="width:100%;height:100%; display:none;"></textarea>
          </div>
        </div>
        text<div @click="delData(index)">-删除</div>
      </div>
      <div class="barArea" v-else-if="item.type === 'image'">
        <input type="file" accept="image/gif,image/jpeg,image/png" @change="changeFn(item, index, $event)" />
        image<div @click="delData(index)">-删除</div>
      </div>
      <div class="barArea" v-else-if="item.type === 'audio'">
        <input type="file" accept="audio/*" @change="changeFn(item, index, $event)" />
        audio<div @click="delData(index)">-删除</div>
      </div>
      <div class="barArea" v-else-if="item.type === 'video'">
        <input type="file" accept="video/*" @change="changeFn(item, index, $event)" />
        video<div @click="delData(index)">-删除</div>
      </div>
    </div>
    {{dataArr}}
    <div class="barArea">
      <div class="fnBtn" @click="addData('text')">+文字</div>
      <div class="fnBtn" @click="addData('image')">+图片</div>
      <div class="fnBtn" @click="addData('audio')">+音频</div>
      <div class="fnBtn" @click="addData('video')">+视频</div>
    </div>
  </div>

  <script>
    window.esEditor = {
      isFormat: false,
      editor: "", //获取iframe Window 对象
      doc: "", //获取iframe documen 对象
      // editor: document.getElementsByClassName("HtmlEdit")[0].contentWindow, //获取iframe Window 对象
      // doc: document.getElementsByClassName("HtmlEdit")[0].contentDocument, //获取iframe documen 对象
      // box: document.getElementById('box'),
      iframeJqDOC: '',
      dataSetting: function (id) {
        setTimeout(function () {
          // console.log($(".HtmlEdit"))
          var iframeElem = $(".es-richText:eq(" + id + ")").find(".HtmlEdit").get(0);
          this.editor = iframeElem.contentWindow;
          this.doc = iframeElem.contentDocument;
          this.EditorInitSetting(id);
        }.bind(this))

        // $(".HtmlEdit")[id].ready(function () {
        //   esEditor.EditorInitSetting();
        // })
        // setTimeout(function () {
        //   this.EditorInitSetting();
        // }.bind(this))
      },
      EditorInitSetting: function (id) {
        this.editor.document.designMode = 'On'; //打开设计模式
        this.editor.document.contentEditable = true; // 设置元素为可编辑
        var scr = HTMLDecode("&lt;script src='../Library/jquery/jquery-3.6.0.js'&gt;&lt;/script&gt;");
        this.doc.write(scr);
        var js = HTMLDecode(`&lt;script&gt;
          var listId = ` + id + `;
          function hide(ele) {
            window.parent.esEditor.autoFormat($(document));
          }
          // 点击事件 设置编辑器选中态
          $(document).on("mousedown", function () {
            window.parent.esEditor.getFocus($(document), listId); //, textId
          })
          // 点击事件 设置文字框选态
          $(document).on("mouseup", function () {
            window.parent.esEditor.fixSel();
          })
        &lt;/script&gt;`)
        this.doc.write("<div class='spaceMask' style='position:fixed;top:0;left:0;right:0;bottom:0;' onmousedown='hide($(this))'></div>");
        this.doc.write(js);
        this.doc.getElementsByTagName("head")[0].innerHTML += HTMLDecode(`&lt;style&gt;
          p {
            word-wrap: break-word;
            word-break: break-all;
          }
        &lt;/style&gt;`)
        $(".toolbar[listid!=" + id + "]").fadeOut(300);
        $(".toolbar[listid=" + id + "]").fadeIn(300);
      },
      getFocus: function (ele, listId) {
        this.iframeJqDOC = ele;
        var iframeElem = $(".es-richText:eq(" + listId + ")").find(".HtmlEdit").get(0);
        this.editor = iframeElem.contentWindow;
        this.doc = iframeElem.contentDocument;
        $(".toolbar[listid!=" + listId + "]").fadeOut(300);
        $(".toolbar[listid=" + listId + "]").fadeIn(300);
      },
      fixSel: function () {
        console.log(this.editor.document.execCommand('fontSize', false));
      },
      undo: function () {
        this.editor.document.execCommand('undo', false, null); // 撤销
      },
      redo: function () {
        this.editor.document.execCommand('redo', false, null); // 恢复
      },
      indent: function () {
        this.editor.document.execCommand("Indent"); // 增加选中文本的缩进。
      },
      // 加粗
      bold: function () {
        this.editor.document.execCommand('bold', false, null)
      },
      // 斜体
      italic: function () {
        this.editor.document.execCommand('italic', false, null)
      },
      // 下划线
      underline: function () {
        this.editor.document.execCommand('underline', false, null)
      },
      // 删除线
      strikeThrough: function () {
        this.editor.document.execCommand('strikeThrough', false, null)
      },
      // H1
      h1: function () {
        this.editor.document.execCommand('fontSize', false, 7)
      },
      // H2
      h2: function () {
        this.editor.document.execCommand('fontSize', false, 6)
      },
      // H3
      h3: function () {
        this.editor.document.execCommand('fontSize', false, 5)
      },
      fontSize: function (val) {
        this.editor.document.execCommand('fontSize', false, val)
      },
      // 字体颜色
      foreColor: function () {
        this.editor.document.execCommand('foreColor', false, 'red')
      },
      // 字体背景
      hiliteColor: function () {
        this.editor.document.execCommand('hiliteColor', false, 'yellow')
      },
      // 有序列表
      insertOrderedList: function () {
        this.editor.document.execCommand('insertOrderedList', false, null)
      },
      // 无序列表
      insertUnorderedList: function () {
        this.editor.document.execCommand('insertUnorderedList', false, null)
      },
      // 格式序列化
      format: function () {
        this.editor.document.execCommand('formatblock', false, 'p');
      },
      lineHeight: function () {
        this.iframeJqDOC.find("p").css("lineHeight", 2)
      },
      insertEMSP: function () {
        this.editor.document.execCommand('insertText', false, HTMLDecode('&emsp;&emsp;'));
      },
      eventHandler: function (e) {

      },
      // 格式序列化（首次点击文本框触发）
      autoFormat: function (ele) {
        // ele.find("body").find("script,#space").remove();
        ele.find("body").find(".spaceMask").remove();
        this.iframeJqDOC = ele;
        /* 节点改变监听 */
        // ele.bind("DOMNodeInserted", function (e) {
        //   setTimeout(function () {
        //     // ele.find("p").css({
        //     //   "text-indent": "2em"
        //     // })
        //   })
        // })
        setTimeout(function () {
          this.editor.document.execCommand('formatblock', false, 'p');
        }.bind(this))
      },
      // 提交（过滤多余的标签）
      save: function () {
        // 导出
        console.log(this.jsFilter())
        // this.box.innerHTML = this.jsFilter()
      },
      // 过滤
      jsFilter: function () {
        var temp = document.createElement("div");
        $(temp).html(this.doc.body.innerHTML)
        $(temp).find("script").remove();
        return temp.innerHTML
      },
      toHtml: function (ele) {
        // 切换为源码视图
        $(this.doc).find(".spaceMask").trigger("mousedown")
        $(this.doc).find("body").trigger("focus")
        var cursor = ele.parents(".es-richText");
        setTimeout(function () {
          cursor.find(".HtmlEdit").hide();
          cursor.find(".HtmlView").fadeIn(300);
          cursor.find(".HtmlView").val(this.jsFilter()); // 编辑继承
          cursor.find(".toHtml_btn").hide();
          cursor.find(".toView_btn").fadeIn(300);
          cursor.find(".htmlHide").css({
            "opacity": 0,
            "cursor": "default",
            "pointer-events": "none"
          });
        }.bind(this))
      },
      toView: function (ele) {
        var cursor = ele.parents(".es-richText");
        // 切换为效果视图
        cursor.find(".HtmlView").hide();
        cursor.find(".HtmlEdit").fadeIn(300);
        this.doc.body.innerHTML = cursor.find(".HtmlView").val()
        cursor.find(".toView_btn").hide();
        cursor.find(".toHtml_btn").fadeIn(300);
        cursor.find(".htmlHide").css({
          "opacity": 1,
          "cursor": "pointer",
          "pointer-events": "auto"
        });
      }
    }

    var vueApp = new Vue({
      el: "#app",
      data: {
        id: 0,
        // textId: 0,
        dataArr: [],
      },
      mounted() { // 调试
        this.addData("text")
      },
      methods: {
        // 增
        addData: function (type) {
          this.dataArr.push({
            "id": this.id,
            "type": type,
          });
          if (type === "text") {
            // console.log(window.esEditor)
            window.esEditor.dataSetting(this.id); // this.textId,
            // window.esEditor.EditorInitSetting(this.textId);
            // this.textId++;
          }
          this.id++;
        },
        // 删
        delData: function (index) {
          this.dataArr.splice(index, 1);
        },
        // 改
        changeFn: function (data, index, event) {
          // this.dataArr[index].url = 
        }
      }
    })

    /* VUE图片上传 */
    // if (this.dataArr[index].type !== data.type) return false
    // var file = event.target.files[0]; //获取图片资源
    // var fileTypes = ["bmp", "jpg", "png", "jpeg"];
    // var bTypeMatch = false
    // for (var i = 0; i < fileTypes.length; i++) {
    //   var start = file.name.lastIndexOf(".");
    //   var fileType = file.name.substring(start + 1);
    //   if (fileType.toLowerCase() == fileTypes[i]) {
    //     bTypeMatch = true;
    //     break;
    //   }
    // }
    // if (bTypeMatch) {
    //   if (file.size <= 1024 * 1024 * 10) { // 10MB
    //     var reader = new FileReader();
    //     reader.readAsDataURL(file); // 读取文件
    //     // 渲染文件
    //     reader.onload = function (arg) {
    //       $(".imageShow").show()
    //       $("#uploadImageShow").attr("src", arg.target.result)
    //       btnUploadText = '重新上传'
    //       $("#uploadButton").text(btnUploadText)
    //     }
    //   } else {
    //     alert('仅支持不超过10M的图片');
    //     emptyImageUpload("#imagePic")
    //     $("#uploadImageShow").attr("src", "")
    //     $(".imageShow").hide()
    //     btnUploadText = '上传'
    //     $("#uploadButton").text(btnUploadText)
    //     return false;
    //   }
    // } else {
    //   alert('仅限bmp，jpg，png，jpeg图片格式');
    //   emptyImageUpload("#imagePic")
    //   $("#uploadImageShow").attr("src", "")
    //   $(".imageShow").hide()
    //   btnUploadText = '上传'
    //   $("#uploadButton").text(btnUploadText)
    //   return false;
    // }

    function getObjectURL(file) {
      var url = null;
      if (window.createObjectURL != undefined) { // basic
        url = window.createObjectURL(file);
      } else if (window.URL != undefined) { // mozilla(firefox)
        url = window.URL.createObjectURL(file);
      } else if (window.webkitURL != undefined) { // webkit or chrome
        url = window.webkitURL.createObjectURL(file);
      }
      return url;
    }

    function HTMLEncode(html) {
      var temp = document.createElement("div");
      (temp.textContent != null) ? (temp.textContent = html) : (temp.innerText = html);
      var output = temp.innerHTML;
      temp = null;
      return output;
    }

    function HTMLDecode(text) {
      var temp = document.createElement("div");
      temp.innerHTML = text;
      var output = temp.innerText || temp.textContent;
      temp = null;
      return output;
    }
  </script>

  <!-- <div style="display: flex;">
    <div id="box" class="trueView"></div>

  </div> -->
</body>

</html>